package com.itheima.service.impl;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.common.TokenHolder;
import com.itheima.constant.CommonConstant;
import com.itheima.dto.PutStatusDTO;
import com.itheima.entity.*;
import com.itheima.mapper.*;
import com.itheima.service.OrderService;
import com.itheima.service.ShoppingService;
import com.itheima.vo.OrderPageResult;
import com.itheima.vo.OrderPageResultVO;
import com.itheima.vo.OrderPageVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
 *订单模块业务层实现类
 * @author msi
 * @date 2022/5/17
 * @version 1.0
 */
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderMapper mapper;
    @Autowired
    private AddressMapper addressMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private OrderDetailsMapper orderDetailsMapper;
    @Resource
    private RedisTemplate<Object, Object> redisTemplate;
    @Resource
    private ShoppingService service;
    @Resource
    private DishMapper dishMapper;
    @Resource
    private SetmealMapper setmealMapper;

    @Override
    public OrderPageVO getPageList(String beginTime, String endTime, String number, Integer page, Integer pageSize) {

        OrderPageVO orderPageVO = new OrderPageVO();
        QueryWrapper<Order> qw = new QueryWrapper<>();
        if (number != null) {
            qw.eq("number", number);
        }
        if (beginTime != null && endTime != null) {

            qw.apply("UNIX_TIMESTAMP(order_time) >= UNIX_TIMESTAMP('" + beginTime + "')");
            qw.apply("UNIX_TIMESTAMP(order_time) <= UNIX_TIMESTAMP('" + endTime + "')");
        }
        IPage<Order> iPage = new Page<>(page, pageSize);
        mapper.selectPage(iPage, qw);
        orderPageVO.setRecords(iPage.getRecords());
        orderPageVO.setCurrent(page);
        orderPageVO.setSize(pageSize);
        orderPageVO.setTotal(iPage.getTotal());

        return orderPageVO;
    }

    @Override
    public OrderPageResultVO getPageList(Integer page, Integer pageSize) {

        IPage<Order> iPage = new Page<>(page, pageSize);
        mapper.selectPage(iPage, null);
        List<Order> records = iPage.getRecords();
        List<OrderPageResult> pageResultList = new ArrayList<>();

        for (Order order : records) {
            OrderPageResult pageResult = new OrderPageResult();
            BeanUtils.copyProperties(order, pageResult);

            QueryWrapper<OrderDetails> qw = new QueryWrapper<>();
            qw.eq("order_id", order.getId());
            List<OrderDetails> orderDetails = orderDetailsMapper.selectList(qw);
            pageResult.setOrderDetails(orderDetails);
            pageResultList.add(pageResult);
        }

        OrderPageResultVO orderPageVO = new OrderPageResultVO();
        orderPageVO.setRecords(pageResultList);
        orderPageVO.setCurrent(page);
        orderPageVO.setSize(pageSize);
        orderPageVO.setTotal(iPage.getTotal());
        orderPageVO.setPages(iPage.getPages());
        orderPageVO.setOptimizeCountSql(true);
        orderPageVO.setHitCount(false);
        orderPageVO.setCountId(null);
        orderPageVO.setMaxLimit(null);
        orderPageVO.setSearchCount(true);

        return orderPageVO;
    }


    @Override
    public Boolean updateStatus(PutStatusDTO putStatusDTO) {
        Integer status = putStatusDTO.getStatus();
        String id = putStatusDTO.getId();
        UpdateWrapper<Order> uw = new UpdateWrapper<>();
        uw.eq("id", id);
        uw.set("status", status);
        int update = mapper.update(null, uw);

        return update > 0;
    }



    @Override
    public Boolean insert(Order order) {

        String userId = TokenHolder.getCurrentId();
        order.setUserId(userId);

        Snowflake snowflake = IdUtil.getSnowflake();
        String id = snowflake.nextIdStr();
        order.setId(id);
        String number = snowflake.nextIdStr();
        order.setNumber(number);
        order.setOrderTime(new Date());
        order.setCheckoutTime(new Date());

        String key = CommonConstant.CART_DISH + userId;

        List<ShoppingCart> shoppingCarts = (List<ShoppingCart>) redisTemplate.opsForValue().get(key);
        //遍历购物车的商品加入到订单明细表中
        int amount = 0;
        for (ShoppingCart cart : shoppingCarts) {
            Integer amount1 = cart.getAmount();
            Integer number1 = cart.getNumber();
            amount = amount + (amount1 * number1);
            if (cart.getDishId() != null) {
                Dish dish = dishMapper.selectById(cart.getDishId());
                dish.setSaleNum(dish.getSaleNum() + number1);
                dishMapper.updateByDishId(dish);
                //更改销量后不再事实刷新redis缓存 因为销量没必要实时显示
            }
            if (cart.getSetmealId() != null) {
                Setmeal setmeal = setmealMapper.selectById(cart.getSetmealId());
                setmeal.setSaleNum(setmeal.getSaleNum() + number1);
                setmealMapper.updateBySetmealId(setmeal);
            }
            OrderDetails orderDetails = new OrderDetails();
            orderDetails.setOrderId(id);
            orderDetails.setName(cart.getName());
            orderDetails.setNumber(cart.getNumber());
            orderDetailsMapper.insert(orderDetails);
        }

        order.setAmount(amount);
        AddressBook oneAddress = addressMapper.getOneAddress(order.getAddressBookId());
        order.setPhone(oneAddress.getPhone());
        order.setAddress(oneAddress.getDetail());
        order.setConsignee(oneAddress.getConsignee());
        User user = userMapper.selectById(userId);
        order.setUserName(user.getUsername());
        order.setStatus(2);

        int insert = mapper.insert(order);
        //提交订单清空购物车
        service.clean(userId);

        return insert > 0;
    }
}
